import { JXDef } from '../../../conventions/JXCommon';
import GEventSystem from '../../../Core/GEvent/GEventSystem';
import { AudioMgr } from '../../../Core/Manager/AudioMgr';
import MathEx from '../../../Core/Math/MathEx';
import { BUFFINFO, CMsg, CURRENCY, ITEM_TYPE, PART_BTL_SCENE } from '../../Common/Define';
import { VIEW_ID } from '../../Common/UI';
import { Res } from '../../Common/UIResources';
import BtlCameraMap from '../../Logic/BtlMap/BtlCameraMap';
import BtlMapConverts from '../../Logic/BtlMap/BtlMapCanverts';
import GameMgr from '../../Logic/GameMgr';
import HeroChange from '../Hero/HeroChange';
import { INVALID_VALUE, IS_EMPTY_INVALID, PRIORITY_VIEW } from './../../../Core/CoreDefine';
import { MapWrap, ObjectWrap } from './../../../Core/FrameEx/ES5Ex';
import { GCtrl } from './../../../Core/GCtrl';
import { JXBattleAnalysis } from './JXBattleAnalysis';
import { JXBattleCb } from './JXBattleCb';
import { JXBattleEvt, JXBtlAns_PressModel, JXBtlArrIx, JXBtlCamp } from './JXBattleDefine';
import JXBtlMgr from './JXBattleManager';
import JXBtlMonsterFactory from './JXBattleMonster';
import { JXRBAmbient } from './JXRBAmbient';
import { JXRBBuff } from './JXRBBuff';
import { JXRBRole } from './JXRBRole';
import JXRBRoleHead from './JXRBRoleHead';
import { JXRBScript$Ambient, JXRBScript$BulletAtk, JXRBScript$DriftAct, JXRBScript$DriftActBullet, JXRBScript$MulNearAtk, JXRBScript$OnceNearAtk, JXRBScript$RoadAct, JXRBScript$SegmentAct, JXRBScript$SegmentNAct, JXRBScript$SegmentTAct, JXRBScript$StandAct, JXRBScript$SyncMoveAct, JXRBScript$SyncMoveActBullet } from './JXRBScript';
import { BattleAssets } from './JXULAsset';
import { DescribeType, ICampKeyCode, JXBattleSkillSpine, JXCLActionConfigure, JXEScriptID, JXEState, JXMsg, JXRB_ROLE_NAME_PREFIX, JXStaticEffects } from './JXULDefine';
export const ANIMATION_SPEED = 1.2;
/**命令管理器 */
export default class JXRBCmdMgr extends ObjectWrap implements IComLike {
	/**所有得角色 */
	protected _roles: MapWrap<string, JXRBRole>
	/** 执行状态 */
	protected _running: boolean;
	/** 播放速度 */
	protected _speed: number = 1.2;
	/**  是否暂停中 */
	protected _pause: boolean = false;
	/** 暂停新的命令 */
	protected _pauseCmd: boolean = false;

	/** 战斗事件管理器 */
	public evtMgr: GEventSystem;
	/**战斗结果分析 */
	public jxBtlAns: JXBattleAnalysis;
	/** 战斗资源管理器 */
	public assetManager: BattleAssets;

	/**坐标转换器 */
	public btlMapConverts: BtlMapConverts;

	/**战斗地图层 */
	public btlCameraMap: BtlCameraMap;

	public isEnd: boolean = false;

	public monsterFactory: JXBtlMonsterFactory = null;

	/** 重要命令延迟执行的事件 */
	protected _changeRoleTime: number = 0;
	/** 等待当前动作池清空 */
	protected _waitCleanActions: boolean = false;

	protected _monsterIndex = 1000;

	protected _wheat: number = 0;
	public get wheat() {
		return this._wheat;
	}
	public addWheat(v: number) {
		this._wheat += v;
	}

	public _wave: cc.Label = null;
	/**每秒粮草提升数量 */
	protected _wheatAdd: number = 0;


	/**场景 */
	protected _sceneId: number = 0;
	public get sceneId() {
		return this._sceneId;
	}

	public monsterCtrl: Function = null;

	protected _count: number = 1;
	public rootNode: cc.Node;
	private _heroCount: number[] = [];
	private level: number = 0;

	constructor(sceneId: number, nameFlag: string, level: number) {
		super();
		this.level = level;
		this.isEnd = false;
		this.initJXBattleCb();
		this._sceneId = sceneId;
		this._heroCount = [0, 0];
		this.assetManager = new BattleAssets(nameFlag);
		this.monsterFactory = new JXBtlMonsterFactory();
		this._roles = new MapWrap<string, JXRBRole>();
		this.evtMgr = new GEventSystem();
		this._wheat = GameMgr.systemConfig.value(JXDef.SYS_CONFIG_KEY.basicsWheat);
		let isOpen = GameMgr.rHeroData.openBook
		if (isOpen) {
			this._wheat *= 3;
			GameMgr.rHeroData.openBook = false;
		}
		this._wheat += GameMgr.lUserData.getUserBuff(BUFFINFO.InitBattlefieldRes);
		this._wheat += GameMgr.RBagData.getMegreItems(CURRENCY.WHEAT, ITEM_TYPE.CURRENCY).num;
		this._wheatAdd = GameMgr.systemConfig.value(JXDef.SYS_CONFIG_KEY.wheatTime);
		setTimeout(() => {
			GCtrl.ES.emit(CMsg.client.bag.onBagItemChange, [[CURRENCY.WHEAT, ITEM_TYPE.CURRENCY, (-GameMgr.RBagData.getMegreItems(CURRENCY.WHEAT, ITEM_TYPE.CURRENCY).num)]]);
		}, 1000);

		GCtrl.ES.emit(CMsg.client.fight_ui.onWheatChange)
		this.registerEvent();
	}



	/**注册事件 */
	protected registerEvent() {
		this.evtMgr.register(JXMsg.action.scExit, this, this.onSCExit.bind(this), PRIORITY_VIEW);
		GCtrl.ES.on(JXMsg.action.debuger.pause, this, this.onMsgPause.bind(this), PRIORITY_VIEW);
		GCtrl.ES.on(GCtrl.GTimerSecondEventMsg, this, this.onSecondTimeAdd.bind(this), PRIORITY_VIEW);
		GCtrl.ES.on(CMsg.data.onClientGuideChange, this, this.onClientGuideChange.bind(this), PRIORITY_VIEW);
		cc.game.on(cc.game.EVENT_SHOW, () => {
			this._pause = false;
		})
		cc.game.on(cc.game.EVENT_HIDE, () => {
			this._pause = true;
		})
	}

	protected onClientGuideChange() {
		if (this._sceneId === PART_BTL_SCENE.GUANQIA && this.level === 1 && !this._running && GameMgr.lUserData.isGuidseExits(1)) {
			this.startCmd();
		}
	}

	protected onSecondTimeAdd() {
		let haveResult = GameMgr.uiMgr.getView(VIEW_ID.battleResult);
		if (!this._pause && this.jxBtlAns && !haveResult) {
			this._wheat += this._wheatAdd;
			GCtrl.ES.emit(CMsg.client.fight_ui.onWheatChange)
		}
	}

	public expendWheat(v: number) {
		this._wheat -= v;
		GCtrl.ES.emit(CMsg.client.fight_ui.onWheatChange)
	}

	protected initJXBattleCb() {
		JXBattleCb.getCardData = (cardId: number) => {
			return GameMgr.heroData.getRaw<SHeroDataRaw>(cardId);
		}
		JXBattleCb.getSkillData = (skillId: number) => {
			return GameMgr.skillData.getRaw<SSkillDataRaw>(skillId);
		}
		JXBattleCb.getBuffData = (buffId: number) => {
			return GameMgr.buffData.getRaw<SBuffDataRaw>(buffId);

		}
		JXBattleCb.getEffectData = (effectId: number) => {
			return GameMgr.skillEffect.getRaw<SSkillEffectRaw>(effectId);
		}

		JXBattleCb.getUnitData = (unit: number) => {
			return GameMgr.unitData.getRaw<SUnitDataRaw>(unit);
		}
		JXBattleCb.getPrng = seedrandom;
	}

	/** 实例化游戏场景 */
	public initRDBtlLayer(target: cc.Node) {
		if (!target) return;
		this.rootNode = target;
		return target;
	}


	/**加载场景所需的资源 */
	public loadAllResources(endCb: any) {
		this.assetManager.loadAllRoundAssets([this.jxBtlAns.iBtlTeams[JXBtlCamp.Attacker], this.jxBtlAns.defTPL], this._sceneId, () => {
			endCb();
		})
	}

	/** 创建一个环境对象 */
	public createAmbient(ambientId: string, camp: JXBtlCamp): JXRBAmbient {
		let node = new cc.Node(ambientId);
		let ambient = new JXRBAmbient(node);
		ambient.cmd = this;
		ambient.id = ambientId;
		ambient._name = camp == JXBtlCamp.Attacker ? "ATKAmbient" : JXBtlCamp.Defenser ? "DEFAmbient" : "NOAmbient";
		this.addRole(ambient, ambient.id);
		return ambient;
	}

	/**添加角色 */
	public addRole(role: JXRBRole, id: string) {
		if (this._roles.has(id)) return;
		role.parent = this.rootNode;
		this._roles.set(id, role);
	}

	/**将角色移除 但是界面没有移除 */
	public removeDefRole(id: string) {
		if (this._roles.has(id)) {
			this._roles.delete(id);
		}
	}



	/**创建模型角色模型*/
	protected createRoleModel<T extends JXRBRole>(comp: JXBtlCamp, model: string, type: { new(object: cc.Node): T }, iKey: number, id: string): T {
		let prefab = this.assetManager.assetImpl.getPreLoadAsset<cc.Prefab>(Res.prefab.fight.role);
		if (!prefab) return;
		let roleNode = cc.instantiate(prefab);
		this._heroCount[comp] = this._heroCount[comp] + 1;
		roleNode.name = JXRB_ROLE_NAME_PREFIX + `_${comp == JXBtlCamp.Attacker ? 'Atk' : 'Def'}_${this._heroCount[comp]}`;
		let roleSk = roleNode.getChildComByName('skeleton', sp.Skeleton);
		if (!roleSk) return;
		roleSk.skeletonData = this.assetManager.assetImpl.getPreLoadAsset<sp.SkeletonData>(model);
		roleSk.defaultSkin = "skin1";
		let role = new type(roleNode);
		role.cmd = this;
		role.id = id;
		role.iKey = iKey;
		role.initState();
		role.setModel(model);
		role.setCamp(comp);
		return role;
	}

	/**创建角色 */
	public createRole(heroId: string, index: number, camp: JXBtlCamp, road?: number[], pos?: cc.Vec2) {
		if (IS_EMPTY_INVALID(heroId)) return;
		if (!road && !pos) {
			cc.error("无效路径或生成点英雄创建失败：" + heroId);
			return;
		}
		let ccPos = road ? GameMgr.mapMgr.decodeXxyy(road[0]) : pos;
		let iTeam = this.jxBtlAns.iBtlTeams[camp];
		let role: JXRBRole;
		let bossRaw: SHeroDataRaw;
		let heroData: IHeroBtlData;
		for (let i = 0; i < iTeam.partnerData.length; i++) {
			if (iTeam.partnerData[i].heroId == heroId) {
				heroData = iTeam.partnerData[i];
				break;
			}
		}
		bossRaw = GameMgr.heroData.getRaw<SHeroDataRaw>(heroData.tableId);
		role = this.createRoleModel(camp, Res.model + bossRaw.animation + "/" + bossRaw.animation, JXRBRole, camp * ICampKeyCode + this._count, heroData.heroId);
		role.wheatUp = bossRaw.wheatUp;
		this.addRole(role, role.id);
		let scale = role.scale;
		let size = cc.size(role.skeleton.node.width * scale, role.skeleton.node.height * scale);
		role.skeleton.node["sWidth"] = size.width;
		role.skeleton.node["sHeight"] = size.height;
		let stand = role.target.getComponent(HeroChange);
		stand && stand.init(heroData as any);
		role.postfix = stand.skillPostfix;
		this._count++;
		if (heroData.nickName) {
			role._name = heroData.nickName;
		} else {
			role._name = bossRaw.name;
		}
		role.tableId = heroData.tableId;
		role.unitId = heroData.unitId;
		role.lv = 1;
		if (!role) return;
		let uiNode = role.target.getChildByName("ui");
		let head = this.assetManager.assetImpl.addGChild<JXRBRoleHead>(Res.prefab.fight.head);
		head.node.parent = uiNode;
		role.setBirthPos(ccPos);
		role.zIndex = this._monsterIndex--;
		if (road) {
			role.setAirPos(GameMgr.mapMgr.decodeXxyy(road[1]));
			role.setRoad(road);
		}
		role.initHeadCtrl(head);
		role.initHp(this.jxBtlAns.maxHps[role.id]);
		role.index = index;
		role.comAtkActionId = bossRaw.action;
		role.vSpeedX = cc.v2(bossRaw.ms, 0);
		role.vSpeedY = cc.v2(0, bossRaw.ms);
		role.skeleton.timeScale = ANIMATION_SPEED * this._speed;
		if (pos) {
			role.changeState(JXEState.Idle);
		} else {
			role.changeState(JXEState.Run);
		}
		role.pushWaitRoles(role)
	}

	/* */
	public checkCanPutOn(camp: JXBtlCamp, pos): JXRBRole {
		let canPutOn = null;
		let roles = this._roles.values<JXRBRole>();
		for (let i = 0; i < roles.length; i++) {
			let role = roles[i];
			let rolePos = this.btlMapConverts.converToMapPos(role.birthPos);
			if (role.camp === camp && pos.x === rolePos.x && pos.y === rolePos.y && role.getCurState() != JXEState.Death) {
				canPutOn = role
				break;
			}
		}
		return canPutOn
	}

	/**数值获取 */
	public numberParse(num: string, isCrit: boolean) {
		let nums = num.split('');
		let ret = "";
		let S = nums[0] == '+' ? "G_" : "R_";
		if (isCrit) {
			S = num[0] == '+' ? "Gcrit_" : "Rcrit_";
		}
		for (let i = 0; i < nums.length; i++) {
			ret += (S + nums[i])
			if (i != nums.length - 1) {
				ret += '|';
			}
		}
		return ret;
	}

	/**获取角色通过Id */
	public getRoleById(id: string): JXRBRole {
		return this._roles.get(id);
	}

	public getSpeed(): number {
		return this._speed;
	}

	public pause() {
		this._pause = true;
	}

	public pauseCmd() {
		this._pauseCmd = true;
	}

	public resume() {
		this._pause = false;
	}

	public resumeCmd() {
		this._pauseCmd = false;
	}

	public get isPause() {
		return this._pause;
	}

	public get isRunning() {
		return this._running;
	}

	public get isPauseCmd() {
		return this._pauseCmd;
	}

	/// event deail
	onSCExit(_, execer: JXRBRole) {
		this._running = true;
	}

	//開始戰鬥
	public startCmd() {
		if (this._sceneId === PART_BTL_SCENE.GUANQIA && this.level === 1 && !GameMgr.lUserData.isGuidseExits(1)) {
			return;
		}
		AudioMgr.Ins().playEffect(Res.audio.haojiao);
		this._running = true;
		this.monsterCtrl();
		this.jxBtlAns.DPL_reSetDisPlayInfo();
	}


	public update() {
		if (!this._roles) return;
		if (this._pause) return;
		let dt = cc.director.getDeltaTime();
		dt *= this._speed * ANIMATION_SPEED;
		let role = [...this._roles.values<JXRBRole>()];
		role = MathEx.fisherYatesShuffle(role);
		role.forEach(v => v.update(dt));
		if (this._pauseCmd) return;
		JXBtlMgr.ins.update(dt);
		if (!this._running) return;
		if (this._changeRoleTime) {
			this._changeRoleTime -= dt;
			if (this._changeRoleTime > 0) {
				return;
			}
			this._changeRoleTime = null;
		}

		if (this._running) {
			this._roles.forEach(v => v.doNextCmd());
		}
	}

	public getNextCmd(hero: string) {
		let role = this._roles.get(hero)
		if (!role) return null;
		return role.getNextCmd();
	}

	public parseCmd(action: any[], unEmit: boolean = false) {
		!unEmit && this.evtMgr.post(CMsg.client.fight_ui.CMD_CHANGE, action);
		switch (action[JXBtlArrIx.Zero]) {
			case JXBattleEvt.ROLE_BEGIN: {
				this._changeRoleTime = 0.2;
				break;
			}
			case JXBattleEvt.ROLE_END: {
				let role = this.getRoleById(action[JXBtlArrIx.One]);
				if (!role) break;
				if (!role.checkRoleIsEnd()) {
					role.running = false;
					role.pushWaitRoles(role)
				}
				break;
			}
			case JXBattleEvt.ROLE_COM_ATK: {
				let ansInfo = this.jxBtlAns.hurtInfos[action[JXBtlArrIx.One]];
				this.doComAtkScript(ansInfo);
				break;
			}
			case JXBattleEvt.ROLE_SKILL_PRESS: {
				let ansInfo = this.jxBtlAns.skillInfos[action[JXBtlArrIx.One]];
				this.doSkillScript(ansInfo);
				break;
			}
			case JXBattleEvt.ROLE_SKILL_PREPARE: {
				let role = this.getRoleById(action[JXBtlArrIx.One]);
				if (!role) break;
				let skillId = action[JXBtlArrIx.Two];
				let skillRes = GameMgr.skillData.getRaw<SSkillDataRaw>(skillId);
				if (!skillRes) break;
				if (skillRes.skillSk && role.effectSkeleton) {
					role.effectSkeleton.skeletonData = this.assetManager.assetImpl.getPreLoadAsset<sp.SkeletonData>(JXBattleSkillSpine + skillRes.skillSk);
				}
				role.changeParpareAnimation(skillRes.animGroup[JXBtlArrIx.Zero], skillId);
				this._running = false;
				break;
			}

			case JXBattleEvt.ROLE_ADD_BUFF: {
				this.addBuff(action[JXBtlArrIx.Six], action[JXBtlArrIx.Two], action[JXBtlArrIx.Three], this.jxBtlAns.buffInfos[action[JXBtlArrIx.Two]]);
				break;
			}
			case JXBattleEvt.ROLE_REMOVE_BUFF: {
				this.removeBuff(action[JXBtlArrIx.Five], action[JXBtlArrIx.Two], action[JXBtlArrIx.Three]);
				break;
			}
			case JXBattleEvt.ROLE_SKILL_HURT: {
				let hurtAns = this.jxBtlAns.hurtInfos[action[JXBtlArrIx.One]];
				let role = this.getRoleById(hurtAns.target);
				role.onDamage(hurtAns);
				break;
			}
			case JXBattleEvt.ROLE_SKILL_ADDHP: {
				let addAns = this.jxBtlAns.addHpInfos[action[JXBtlArrIx.One]];
				let role = this.getRoleById(addAns.target);
				if (!addAns.isProtect) {
					role.onAddHp(addAns);
				}
				role.running = false;
				role.pushWaitRoles(role)
				break;
			}
			case JXBattleEvt.ROLE_SKILL_ADDMAXHP: {
				let addMaxAns = this.jxBtlAns.addMaxHpInfos[action[JXBtlArrIx.One]];
				let role = this.getRoleById(addMaxAns.target);
				role.onAddMaxHp(addMaxAns);
				break;
			}

			case JXBattleEvt.ROLE_ATK_2_PROTECT: {
				break;
			}
			case JXBattleEvt.ROLE_HURT_2_PROTECT: {
				break;
			}
			case JXBattleEvt.ROLE_HURT_2_HP: {
				break;
			}

			case JXBattleEvt.ROLE_DIE: {
				let role = this.getRoleById(action[JXBtlArrIx.One]);
				role.onDie();
				break;
			}
			case JXBattleEvt.ROLE_CONTRLED: {
				let role = this.getRoleById(action[JXBtlArrIx.One]);
				let uuid = action[JXBtlArrIx.Three];
				role.createEffect(JXStaticEffects.control); //() => { this._running = true; }
				let buff = this.jxBtlAns.buffInfos[uuid];
				let effectRaw = GameMgr.skillEffect.getRaw<SSkillEffectRaw>(buff.buffId);
				role.showDescribe({ type: DescribeType.Effect, text: effectRaw.effectDes });
				break;
			}
			case JXBattleEvt.ROLE_IMDE: {
				let role = this.getRoleById(action[JXBtlArrIx.One]);
				role.createEffect(JXStaticEffects.resist);
				let effectId = action[JXBtlArrIx.Three];
				let effectRaw = GameMgr.skillEffect.getRaw<SSkillEffectRaw>(effectId);
				role.showDescribe({ type: DescribeType.Effect, text: effectRaw.effectDes });
				break;
			}
			case JXBattleEvt.END_FIGHT: {
				this._roles.forEach(e => {
					e.pushWaitRoles(e)
				})
				this._waitCleanActions = true;
				break;
			}

			default: break;
		}
	}

	/**进行普攻 */
	public doComAtkScript(hurtInfo: JXAnsHurtInfo) {
		this._running = false;
		let atker = this.getRoleById(hurtInfo.execer);
		let configure: JXCLActionConfigure = {
			isSkill: false,
			actionId: atker.comAtkActionId,
			ansInfo: hurtInfo
		}
		let script = this.getActionScript(atker, configure);
		script.setRecordIdx(this.jxBtlAns.Get_DPL_curPlayID(hurtInfo.execer));
		atker.execScript(script);
	}

	/**执行技能脚本 */
	public doSkillScript(ansInfo: JXAnsSkillInfo) {
		this._running = false;
		let execer = this.getRoleById(ansInfo.execer);
		if (!execer) {
			let extra = this.jxBtlAns.extras[ansInfo.execer];
			execer = this.createAmbient(extra.id, extra.camp);
			if (!execer) {
				if (this._running == false) this._running = true;
				return;
			}
		}

		let skillRes = GameMgr.skillData.getRaw<SSkillDataRaw>(ansInfo.skillId);
		let [group, actionId] = skillRes.animGroup
		let configure: JXCLActionConfigure = {
			isSkill: true,
			isPrepare: ansInfo.model == JXBtlAns_PressModel.PrepareEnd,
			actionId: actionId,
			skillGroup: group == INVALID_VALUE ? null : group,
			ansInfo: ansInfo,
			effectSk: skillRes.skillSk,
		}
		if (ansInfo.effects.length == 0) {
			execer.changeState(JXEState.Idle);
			if (this._running == false) this._running = true;
			// this.doNextCmd();
			return;
		}
		this.displaySkillName(execer, skillRes, () => {
			if (!execer.target) return;
			let script = this.getActionScript(execer, configure);
			script.setRecordIdx(this.jxBtlAns.Get_DPL_curPlayID(execer.id));
			execer.execScript(script);
		});
	}

	/** 技能表现 */
	protected displaySkillName(execer: JXRBRole, skillRes: SSkillDataRaw, cb) {
		cb();
	}

	public getActionScript(atker: JXRBRole, aniConfig: JXCLActionConfigure) {
		let actionRaw = GameMgr.action.getRaw<SActionRaw>(aniConfig.actionId);
		switch (actionRaw.scAct) {
			case JXEScriptID.OnceNearAtk: return new JXRBScript$OnceNearAtk(actionRaw).bindCmd(this).bindExecer(atker).bindAniConfigure(aniConfig);
			case JXEScriptID.MulNearAtk: return new JXRBScript$MulNearAtk(actionRaw).bindCmd(this).bindExecer(atker).bindAniConfigure(aniConfig);
			case JXEScriptID.BulletAtk: return new JXRBScript$BulletAtk(actionRaw).bindCmd(this).bindExecer(atker).bindAniConfigure(aniConfig);
			case JXEScriptID.StandAct: return new JXRBScript$StandAct(actionRaw).bindCmd(this).bindExecer(atker).bindAniConfigure(aniConfig);
			case JXEScriptID.RoadMoveAct: return new JXRBScript$RoadAct(actionRaw).bindCmd(this).bindExecer(atker).bindAniConfigure(aniConfig);
			case JXEScriptID.DriftAct: return new JXRBScript$DriftAct(actionRaw).bindCmd(this).bindExecer(atker).bindAniConfigure(aniConfig);
			case JXEScriptID.SyncMoveAct: return new JXRBScript$SyncMoveAct(actionRaw).bindCmd(this).bindExecer(atker).bindAniConfigure(aniConfig);
			case JXEScriptID.SegmentAct: return new JXRBScript$SegmentAct(actionRaw).bindCmd(this).bindExecer(atker).bindAniConfigure(aniConfig);
			case JXEScriptID.SegmentTAct: return new JXRBScript$SegmentTAct(actionRaw).bindCmd(this).bindExecer(atker).bindAniConfigure(aniConfig);
			case JXEScriptID.SegmentNAct: return new JXRBScript$SegmentNAct(actionRaw).bindCmd(this).bindExecer(atker).bindAniConfigure(aniConfig);
			case JXEScriptID.DriftActBullet: return new JXRBScript$DriftActBullet(actionRaw).bindCmd(this).bindExecer(atker).bindAniConfigure(aniConfig);
			case JXEScriptID.SyncMoveActBullet: return new JXRBScript$SyncMoveActBullet(actionRaw).bindCmd(this).bindExecer(atker).bindAniConfigure(aniConfig);
			case JXEScriptID.Ambient: return new JXRBScript$Ambient(actionRaw).bindCmd(this).bindExecer(atker).bindAniConfigure(aniConfig);
			default: break;
		}
	}


	/**添加buff */
	public addBuff(nTargetId: string, uuid: string, skillId: number, ansBuff: JXAnsBuffInfo) {
		let target = this.getRoleById(nTargetId);
		if (ansBuff.imBuffId) {
			return;
		}
		let skillRes = GameMgr.skillData.getRaw<SSkillDataRaw>(skillId);
		if (!target || !skillRes) return;
		target.addBuffTip(uuid);
		let nIndex = ansBuff.index;
		let effectAniId = skillRes.eAnimId[nIndex];
		if (!effectAniId) return;
		let effectRaw = GameMgr.effectAnim.getRaw<SEffectAnimRaw>(effectAniId);
		if (!effectRaw) return;
		let buffs = target.skillBuffs;
		// 冲突规则检测
		let indexBuffs = buffs.get(skillId);
		if (!indexBuffs) {
			indexBuffs = new MapWrap<number, JXRBBuff>();
			buffs.set(skillId, indexBuffs);
		}
		let skillBuff = indexBuffs.get(nIndex);
		if (skillBuff) {
			skillBuff.addInsBuff(uuid);
			return;
		}
		skillBuff = new JXRBBuff(skillId, nIndex, effectRaw, target.cmd);
		skillBuff.addInsBuff(uuid);
		target.addBuff(skillBuff);
	}

	/**移除buff */
	public removeBuff(nTargetId: string, uuid: string, skillId: number) {
		let target = this.getRoleById(nTargetId);
		let skillRes = GameMgr.skillData.getRaw<SSkillDataRaw>(skillId);
		if (!target || !skillRes) return;
		let ansBuff = this.jxBtlAns.buffInfos[uuid];
		if (!ansBuff.lifeRd) return;
		let effectRaw = GameMgr.skillEffect.getRaw<SSkillEffectRaw>(ansBuff.buffId);
		if (!effectRaw) return;
		target.removeUIBuff(effectRaw);
		let nIndex = ansBuff.index;
		let effectAniId = skillRes.eAnimId[nIndex];
		if (!effectAniId) return;
		let effectAnimRaw = GameMgr.effectAnim.getRaw<SEffectAnimRaw>(effectAniId);
		if (!effectAnimRaw) return;
		let buffs = target.skillBuffs;
		let skillBuffs = buffs.get(skillId);
		if (!skillBuffs) return;
		let skillBuff = skillBuffs.get(nIndex);
		if (!skillBuff) return;
		skillBuff.removeInsBuff(uuid);
	}

	protected onMsgPause() {
		if (this._pause) {
			this.resume();
		}
		else {
			this.pause();
		}
	}


	public destroyAssetManager() {
		this.assetManager.destroy();
		this.assetManager = null;
	}


	public destroy() {
		this.destroyAssetManager();
		this.evtMgr.unRegister(this);
		this.monsterFactory.destory();
		GCtrl.ES.off(this);
	}

}